// COMP710 GP Framework
#ifndef __GAME_H_
#define __GAME_H_

#include <vector>
#include <fmod.hpp>
#include <memory>
// Forward delcarations:
class Renderer;
class Sprite;
class Texture;
class Enemy;
class Tank;
class Bullet;
class Scene;


enum GAME_SCENE {
	SCENE_SPLASH,
	SCENE_INSTRUCTION,
	SCENE_GAME_LOOP,
	SCENE_GAME_OVER
};

class Game
{
	// Member methods:
public:
	static Game& GetInstance();
	static void DestroyInstance();
	bool Initialize();
	bool DoGameLoop();
	void GenerateEnemy();
	void Quit();
	void HandleInput();

protected:
	void Process(float deltaTime);
	void Draw(Renderer& renderer);
	void ProcessFrameCounting(float deltaTime);

private:
	Game();
	~Game();
	Game(const Game& game);
	Game& operator=(const Game& game);

	// Member data:
public:

protected:
	static Game* sm_pInstance;
	Renderer* m_pRenderer;
	int m_width, m_height;

	__int64 m_iLastTime;
	float m_fExecutionTime;
	float m_fElaspedSeconds;
	float m_fEnemyGenerationTimer;
	const float SHOOT_INTERVAL = 0.1;
	float m_fShootTimer;
	const float TANK_MOVE_INTERVAL = 0.1;
	float m_fTankMoveTimer;
	const float ENEMY_GENERATION_INTERVAL = 1.0;
	float m_fEnemyMoveTimer;
	const float ENEMY_MOVE_INTERVAL = 0.05;
	int m_iFrameCount;
	int m_iFPS;
	int m_shootCount = 0;
	int m_iScore = 0;
	int m_iBestHistory = 0;

#ifdef USE_LAG
	float m_fLag;
	int m_iUpdateCount;
#endif // USE_LAG

	bool m_bLooping;
	bool m_bGameover_played = false;

private:
	Tank* m_tank;
	std::vector<Bullet*> m_bullets;
	std::vector<std::shared_ptr<Enemy>> m_enemies;
	int m_direction;
	Scene* m_scene;
	GAME_SCENE m_scene_index = SCENE_SPLASH;
	bool m_first = true;
};

#endif // __GAME_H_